-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local validate = require 'mc.validate'
local utils = require 'mc.utils'
local mdb = require 'mc.mdb'

local Time = {}

---@class Time.KeyValueTable
---@field key string
---@field value string
local TKeyValueTable = {}
TKeyValueTable.__index = TKeyValueTable
TKeyValueTable.group = {}

local function TKeyValueTable_from_obj(obj)
    return setmetatable(obj, TKeyValueTable)
end

function TKeyValueTable.new(dict)
    return TKeyValueTable_from_obj(dict)
end

---@param obj Time.KeyValueTable
function TKeyValueTable:init_from_obj(obj)
    self = obj
end

function TKeyValueTable:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TKeyValueTable.group)
end

TKeyValueTable.from_obj = TKeyValueTable_from_obj

TKeyValueTable.proto_property = {}

TKeyValueTable.default = {}

TKeyValueTable.struct = {}

function TKeyValueTable:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    for k, v in pairs(self) do

        validate.Optional(prefix .. 'key', k, 'string', false, errs, need_convert)

        validate.Optional(prefix .. 'value', v, 'string', false, errs, need_convert)

    end

    TKeyValueTable:remove_error_props(errs, self)
    return self
end

function TKeyValueTable:unpack(_)
    return self
end

Time.KeyValueTable = TKeyValueTable

---@class Time.DSTEnabled
---@field DSTEnabled boolean
local TDSTEnabled = {}
TDSTEnabled.__index = TDSTEnabled
TDSTEnabled.group = {}

local function TDSTEnabled_from_obj(obj)
    return setmetatable(obj, TDSTEnabled)
end

function TDSTEnabled.new(DSTEnabled)
    return TDSTEnabled_from_obj({DSTEnabled = DSTEnabled == nil and true or DSTEnabled})
end
---@param obj Time.DSTEnabled
function TDSTEnabled:init_from_obj(obj)
    self.DSTEnabled = obj.DSTEnabled == nil and true or obj.DSTEnabled
end

function TDSTEnabled:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TDSTEnabled.group)
end

TDSTEnabled.from_obj = TDSTEnabled_from_obj

TDSTEnabled.proto_property = {'DSTEnabled'}

TDSTEnabled.default = {false}

TDSTEnabled.struct = {{name = 'DSTEnabled', is_array = false, struct = nil}}

function TDSTEnabled:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'DSTEnabled', self.DSTEnabled, 'bool', true, errs, need_convert)

    TDSTEnabled:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TDSTEnabled.proto_property, errs, need_convert)
    return self
end

function TDSTEnabled:unpack(_)
    return self.DSTEnabled
end

Time.DSTEnabled = TDSTEnabled

---@class Time.SyncStatus
---@field SyncStatus boolean
local TSyncStatus = {}
TSyncStatus.__index = TSyncStatus
TSyncStatus.group = {}

local function TSyncStatus_from_obj(obj)
    return setmetatable(obj, TSyncStatus)
end

function TSyncStatus.new(SyncStatus)
    return TSyncStatus_from_obj({SyncStatus = SyncStatus or false})
end
---@param obj Time.SyncStatus
function TSyncStatus:init_from_obj(obj)
    self.SyncStatus = obj.SyncStatus or false
end

function TSyncStatus:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSyncStatus.group)
end

TSyncStatus.from_obj = TSyncStatus_from_obj

TSyncStatus.proto_property = {'SyncStatus'}

TSyncStatus.default = {false}

TSyncStatus.struct = {{name = 'SyncStatus', is_array = false, struct = nil}}

function TSyncStatus:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'SyncStatus', self.SyncStatus, 'bool', true, errs, need_convert)

    TSyncStatus:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSyncStatus.proto_property, errs, need_convert)
    return self
end

function TSyncStatus:unpack(_)
    return self.SyncStatus
end

Time.SyncStatus = TSyncStatus

---@class Time.TimeZoneName
---@field TimeZoneName string
local TTimeZoneName = {}
TTimeZoneName.__index = TTimeZoneName
TTimeZoneName.group = {}

local function TTimeZoneName_from_obj(obj)
    return setmetatable(obj, TTimeZoneName)
end

function TTimeZoneName.new(TimeZoneName)
    return TTimeZoneName_from_obj({TimeZoneName = TimeZoneName or [=[UTC]=]})
end
---@param obj Time.TimeZoneName
function TTimeZoneName:init_from_obj(obj)
    self.TimeZoneName = obj.TimeZoneName or [=[UTC]=]
end

function TTimeZoneName:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TTimeZoneName.group)
end

TTimeZoneName.from_obj = TTimeZoneName_from_obj

TTimeZoneName.proto_property = {'TimeZoneName'}

TTimeZoneName.default = {''}

TTimeZoneName.struct = {{name = 'TimeZoneName', is_array = false, struct = nil}}

function TTimeZoneName:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'TimeZoneName', self.TimeZoneName, 'string', false, errs, need_convert)

    TTimeZoneName:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TTimeZoneName.proto_property, errs, need_convert)
    return self
end

function TTimeZoneName:unpack(_)
    return self.TimeZoneName
end

Time.TimeZoneName = TTimeZoneName

---@class Time.DateTimeLocalOffset
---@field DateTimeLocalOffset string
local TDateTimeLocalOffset = {}
TDateTimeLocalOffset.__index = TDateTimeLocalOffset
TDateTimeLocalOffset.group = {}

local function TDateTimeLocalOffset_from_obj(obj)
    return setmetatable(obj, TDateTimeLocalOffset)
end

function TDateTimeLocalOffset.new(DateTimeLocalOffset)
    return TDateTimeLocalOffset_from_obj({DateTimeLocalOffset = DateTimeLocalOffset or [=[+00:00]=]})
end
---@param obj Time.DateTimeLocalOffset
function TDateTimeLocalOffset:init_from_obj(obj)
    self.DateTimeLocalOffset = obj.DateTimeLocalOffset or [=[+00:00]=]
end

function TDateTimeLocalOffset:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TDateTimeLocalOffset.group)
end

TDateTimeLocalOffset.from_obj = TDateTimeLocalOffset_from_obj

TDateTimeLocalOffset.proto_property = {'DateTimeLocalOffset'}

TDateTimeLocalOffset.default = {''}

TDateTimeLocalOffset.struct = {{name = 'DateTimeLocalOffset', is_array = false, struct = nil}}

function TDateTimeLocalOffset:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'DateTimeLocalOffset', self.DateTimeLocalOffset, 'string', true, errs, need_convert)

    TDateTimeLocalOffset:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TDateTimeLocalOffset.proto_property, errs, need_convert)
    return self
end

function TDateTimeLocalOffset:unpack(_)
    return self.DateTimeLocalOffset
end

Time.DateTimeLocalOffset = TDateTimeLocalOffset

---@class Time.TimeZoneConfigurable
---@field TimeZoneConfigurable boolean
local TTimeZoneConfigurable = {}
TTimeZoneConfigurable.__index = TTimeZoneConfigurable
TTimeZoneConfigurable.group = {}

local function TTimeZoneConfigurable_from_obj(obj)
    return setmetatable(obj, TTimeZoneConfigurable)
end

function TTimeZoneConfigurable.new(TimeZoneConfigurable)
    return TTimeZoneConfigurable_from_obj({
        TimeZoneConfigurable = TimeZoneConfigurable == nil and true or TimeZoneConfigurable
    })
end
---@param obj Time.TimeZoneConfigurable
function TTimeZoneConfigurable:init_from_obj(obj)
    self.TimeZoneConfigurable = obj.TimeZoneConfigurable == nil and true or obj.TimeZoneConfigurable
end

function TTimeZoneConfigurable:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TTimeZoneConfigurable.group)
end

TTimeZoneConfigurable.from_obj = TTimeZoneConfigurable_from_obj

TTimeZoneConfigurable.proto_property = {'TimeZoneConfigurable'}

TTimeZoneConfigurable.default = {false}

TTimeZoneConfigurable.struct = {{name = 'TimeZoneConfigurable', is_array = false, struct = nil}}

function TTimeZoneConfigurable:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'TimeZoneConfigurable', self.TimeZoneConfigurable, 'bool', true, errs, need_convert)

    TTimeZoneConfigurable:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TTimeZoneConfigurable.proto_property, errs, need_convert)
    return self
end

function TTimeZoneConfigurable:unpack(_)
    return self.TimeZoneConfigurable
end

Time.TimeZoneConfigurable = TTimeZoneConfigurable

---@class Time.DateTime
---@field DateTime string
local TDateTime = {}
TDateTime.__index = TDateTime
TDateTime.group = {}

local function TDateTime_from_obj(obj)
    return setmetatable(obj, TDateTime)
end

function TDateTime.new(DateTime)
    return TDateTime_from_obj({DateTime = DateTime})
end
---@param obj Time.DateTime
function TDateTime:init_from_obj(obj)
    self.DateTime = obj.DateTime
end

function TDateTime:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TDateTime.group)
end

TDateTime.from_obj = TDateTime_from_obj

TDateTime.proto_property = {'DateTime'}

TDateTime.default = {''}

TDateTime.struct = {{name = 'DateTime', is_array = false, struct = nil}}

function TDateTime:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'DateTime', self.DateTime, 'string', true, errs, need_convert)

    TDateTime:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TDateTime.proto_property, errs, need_convert)
    return self
end

function TDateTime:unpack(_)
    return self.DateTime
end

Time.DateTime = TDateTime

---@class Time.SetDateTimeRsp
local TSetDateTimeRsp = {}
TSetDateTimeRsp.__index = TSetDateTimeRsp
TSetDateTimeRsp.group = {}

local function TSetDateTimeRsp_from_obj(obj)
    return setmetatable(obj, TSetDateTimeRsp)
end

function TSetDateTimeRsp.new()
    return TSetDateTimeRsp_from_obj({})
end
---@param obj Time.SetDateTimeRsp
function TSetDateTimeRsp:init_from_obj(obj)

end

function TSetDateTimeRsp:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSetDateTimeRsp.group)
end

TSetDateTimeRsp.from_obj = TSetDateTimeRsp_from_obj

TSetDateTimeRsp.proto_property = {}

TSetDateTimeRsp.default = {}

TSetDateTimeRsp.struct = {}

function TSetDateTimeRsp:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    TSetDateTimeRsp:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSetDateTimeRsp.proto_property, errs, need_convert)
    return self
end

function TSetDateTimeRsp:unpack(_)
end

Time.SetDateTimeRsp = TSetDateTimeRsp

---@class Time.SetDateTimeReq
---@field TimeParams Time.KeyValueTable
local TSetDateTimeReq = {}
TSetDateTimeReq.__index = TSetDateTimeReq
TSetDateTimeReq.group = {}

local function TSetDateTimeReq_from_obj(obj)
    return setmetatable(obj, TSetDateTimeReq)
end

function TSetDateTimeReq.new(TimeParams)
    return TSetDateTimeReq_from_obj({TimeParams = TimeParams})
end
---@param obj Time.SetDateTimeReq
function TSetDateTimeReq:init_from_obj(obj)
    self.TimeParams = obj.TimeParams
end

function TSetDateTimeReq:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSetDateTimeReq.group)
end

TSetDateTimeReq.from_obj = TSetDateTimeReq_from_obj

TSetDateTimeReq.proto_property = {'TimeParams'}

TSetDateTimeReq.default = {Time.KeyValueTable.default}

TSetDateTimeReq.struct = {{name = 'TimeParams', is_array = false, struct = Time.KeyValueTable.struct}}

function TSetDateTimeReq:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    Time.KeyValueTable.new(self.TimeParams):validate(prefix, errs, need_convert)

    TSetDateTimeReq:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSetDateTimeReq.proto_property, errs, need_convert)
    return self
end

function TSetDateTimeReq:unpack(_)
    return self.TimeParams
end

Time.SetDateTimeReq = TSetDateTimeReq

Time.interface = mdb.register_interface('bmc.kepler.Managers.Time', {
    DateTime = {'s', {'VOLATILE'}, true, nil, false},
    TimeZoneConfigurable = {'b', nil, true, true, false},
    DateTimeLocalOffset = {'s', nil, true, '+00:00', false},
    TimeZoneName = {'s', nil, false, 'UTC', false},
    SyncStatus = {'b', {}, true, false, false},
    DSTEnabled = {'b', {}, true, true, false}
}, {SetDateTime = {'a{ss}a{ss}', '', TSetDateTimeReq, TSetDateTimeRsp}}, {})

return Time
